<?php
/**
 * Copyright (c) 2009, Microsoft
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Microsoft nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Microsoft ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Microsoft BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * @category   Microsoft
 * @package    WebErrorPHPToolkit
 * @subpackage SearchKeys
 * @version    $Id: GetSearchKeys.php, v 1.0 2009-10-09 08:00:00Z unknown $
 * @copyright  Copyright (c) 2009, Microsoft (http://www.microsoft.com)
 * @author     a-jetann
 *  
 * Gathers search keys from request URI and prepares for Bing search 
 * query.
 */



/**
 * Acquire search keys for provided request URI.
 * @param string $requestUriStr
 * @return boolean Success status
*/
function web_error_get_bing_search_keys($requestUriStr)
{
  try
  {
    /*
    * Make sure that request URI has a string value greater than zero length.
    */
    if ( !is_string($requestUriStr) || !strlen($requestUriStr) )
    {
      web_error_set_hidden('BingSearchTerms', '');
      return true;
    }

    /*
    * keys begins with the request Uri string, then broken apart and filtered.
    */
    $requestUriStrM = $requestUriStr;

    /*
    * If FileTypeFilterMode:
    * FILTER_MODE_ALL, allow all extensions and ignore listing within FileTypeFilter
    * FILTER_MODE_EXCLUDE, then any extension within FileTypeFilter found, abort query.
    * FILTER_MODE_INCLUDE, then any extension not within FileTypeFilter found, abort query.
    */
    $modeFileTypeFilter = site_variable_get('Custom404FileTypeFilterMode', FILTER_MODE_ALL);
    if ($modeFileTypeFilter != FILTER_MODE_ALL)
    {
      $extensions_array = preg_split('/\s+/', site_variable_get('Custom404FileTypeFilter', ''));
      if (!empty($extensions_array))
      {
        $bool_match_found = in_extension_array($requestUriStrM, $extensions_array, $str_match_found );
        if ((($modeFileTypeFilter == FILTER_MODE_EXCLUDE) && $bool_match_found) // Exclude
        || (($modeFileTypeFilter == FILTER_MODE_INCLUDE) && !$bool_match_found)) // Include
        {
          web_error_set_hidden('BingSearchTerms', '');
          return true;
        }
      }
    }

    /*
    * Ignore certain extensions from query
    * config setting FileTypeExtensionFilter
    */
    $extensions_array = preg_split('/\s+/', site_variable_get('Custom404ExtensionsFilter', ''));
    if (!empty($extensions_array))
    {
      if(in_extension_array($requestUriStrM, $extensions_array, $str_match_found ))
      {
        $requestUriStrM = str_replace(".".$str_match_found, '', $requestUriStrM);
      }
    }

    /*
    * Pre-filter remove undesired expressions from request URI.
    * config setting PCREFilter
    */
    $regex_filter = site_variable_get('Custom404PCREFilter', '');
    if (!empty($regex_filter))
    {
      $requestUriStrM = preg_replace("/".$regex_filter."/", '', $requestUriStrM);
    }

    /*
    * Matches Unicode characters to exclude from search
    */
    $keys = preg_split('/['. PREG_SEARCH_EXCLUDE .']+/u', $requestUriStrM);

    /*
    * Remove any items in the key array that are empty.
    * Artifact of preg_split.
    */
    web_error_remove_empty_keys($keys);
    if (empty($keys))
    {
      web_error_set_hidden('BingSearchTerms', '');
      return true;
    }

    /*
    * Filter out certain words from keys.
    * config setting WordsIgnoreFilter
    */
    $keys = array_diff($keys, explode(' ', site_variable_get('Custom404WordsIgnoreFilter', '')));
    if (empty($keys))
    {
      web_error_set_hidden('BingSearchTerms', '');
      return true;
    }

    /*
    * splice the first keys by maximum number of keys allowed.
    * config setting BingSearchMaximumKeys
    */
    web_error_clean_up_maximum_keys($keys);

    /*
    * Prepare keys to become a string of search terms
    */
    if (!web_error_prepare_search_terms($keys))
    {
      return false;
    }
  }
  catch (Exception $ex)
  {
  	throw new WebToolkit_SearchKeys_Exception($ex->getMessage());
    return false;
  }

  return true;
}

/**
 * Remove any items in keys array that are empty.
 * 
 * @param array $keys
 * @return boolean Success status.
 */
function web_error_remove_empty_keys(&$keys)
{

  // Remove empty elements in array.
  $new_array = array();
  for ($i = 0; $i < count($keys); $i++)
  {
    if ( ($keys[$i] == '') || is_null($keys[$i]) )
    {
      continue;
    }
    $new_array[] = $keys[$i];
  }
  $keys = $new_array;

  return true;
}

/**
 * @category   Microsoft
 * @package    Microsoft_WebErrorPHPToolkit
 * @subpackage SearchKeys
 * @copyright  Copyright (c) 2009, Microsoft (http://www.microsoft.com)
 * @license
 * 
 * Cleanup maximum number of keys.
 * 
 * @param array $keys
 * @return boolean Success status.
 */
function web_error_clean_up_maximum_keys(&$keys)
{

  $keys = string_array_iunque($keys);

  // Take only a slice of the initial keys
  $keys_count = site_variable_get('Custom404MaximumKeys', 0);
  if ( $keys_count > 0 )
  {
    $keys = array_slice($keys, 0, $keys_count);
  }

  // Sanitize the keys
  foreach ($keys as $a => $b)
  {
    $keys[$a] = string_check_plain($b);
  }

  return true;
}

/**
 * Prepare gathered keys for search term.
 * 
 * @param array $keys
 * @return boolean Success status.
 */
function web_error_prepare_search_terms(&$keys)
{

  // Build up search term string for JSON Query
  if (count($keys) > 1)
  {
    $modifier = site_variable_get('Custom404SearchUsingOREnabled', false) ? ' OR ' : ' ';

    $keys = trim(implode($modifier, $keys));

    if (site_variable_get('Custom404SearchUsingOREnabled', false))
    {
      $keys = '('.$keys.')';
    }
  }
  else

  {
    $keys = $keys[0];
  }

  web_error_set_hidden('BingSearchTerms', $keys);

  return true;
}

/**
 * Add domains (site) to gathered search keys.
 * Site domain values are set within BingIncludedDomains.
 * If domain site is provided within BingIncludedDomains,
 * then general Web search is performed instead.
 * @return boolean Success status.
 */
function web_error_get_bing_site_domains()
{
  // Prepend Domains as Keys
  $domain_keys = site_variable_get('BingIncludedDomains', '');
  if ( $domain_keys && is_string($domain_keys) && strlen($domain_keys) > 0 )
  {
    $domain_keys = string_array_iunque(explode(" ", $domain_keys));

    // Build domain query string
    if (count($domain_keys) > 0)
    {
      // Prepend each domain with 'site' to focus 404 search only within this domain.
      array_walk($domain_keys, 'web_error_key_alter_functor', 'site');

      if (count($domain_keys) > 1)
      {
        $modifier = ' | ';
        $domain_keys = '('.trim(implode($modifier, $domain_keys)).')';
      } else
      {
        $domain_keys = $domain_keys[0];
      }
    }
  }

  web_error_set_hidden("BingSiteDomains", $domain_keys);

  return true;
}
?>